package com.xinxuan.usercenter.auth;

import java.lang.reflect.Method;
import java.util.Objects;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.xinxuan.usercenter.util.JwtOperator;

import io.jsonwebtoken.Claims;

/**
 * @author xinsl
 * @date 2022/1/6
 */
@Aspect
@Component
public class AuthAspect {
    @Resource
    private JwtOperator jwtOperator;

    @Around("@annotation(com.xinxuan.usercenter.auth.CheckLogin)")
    public Object checkLogin(ProceedingJoinPoint point) throws Throwable {
        // 1.从header里面获取token
        checkToken();
        return point.proceed();

        // 2.校验token是否合法 合法放行 不合法抛异常
    }

    private void checkToken() {
        try {
            HttpServletRequest request = getHttpServletRequest();
            String token = request.getHeader("X-Token");
            // 校验token是否合法&国企
            Boolean isValid = jwtOperator.validateToken(token);
            if (!isValid) {
                throw new SecurityException("Token不合法！");
            }
            // 如果校验成功 九八用户信息设置到request的attribute里面
            Claims claims = jwtOperator.getClaimsFromToken(token);
            request.setAttribute("id", claims.get("id"));
            request.setAttribute("wxNickname", claims.get("wxNickname"));
            request.setAttribute("role", claims.get("role"));
        } catch (Throwable throwable) {
            throw new SecurityException("Token不合法");
        }
    }

    private HttpServletRequest getHttpServletRequest() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes attributes = (ServletRequestAttributes)requestAttributes;
        return attributes.getRequest();
    }

    @Around("@annotation(com.xinxuan.usercenter.auth.CheckAuthorization)")
    public Object CheckAuthorization(ProceedingJoinPoint point) throws Throwable {
        // 1.验证token是否合法
        // 2.验证角色是否匹配
        checkToken();
        HttpServletRequest request = getHttpServletRequest();
        String role = (String)request.getAttribute("role");
        MethodSignature signature = (MethodSignature)point.getSignature();
        Method method = signature.getMethod();
        CheckAuthorization annotation = method.getAnnotation(CheckAuthorization.class);
        String value = annotation.value();
        if (!Objects.equals(role, value)) {
            throw new SecurityException("用户无权访问！");
        }

        return point.proceed();
        // 2.校验token是否合法 合法放行 不合法抛异常
    }
}
